#include "header.h"
#include "util.h"

int power(int base, int exp)
{
  int product = 1;
  for(int i = exp; i > 0; i--)
    product *= base;
  return product;
}


static char_t symbols[] = "{}[]()!'£$%^&*-+=:;@~#<>,.?/\\|_\"";

char_t is_bracket(char_t ch) {
    switch (ch) {
        case '[': return ']';
        case '(': return ')';
        case '{': return '}';
        case '<': return '>';
        case ']': return '[';
        case ')': return '(';
        case '}': return '{';
        case '>': return '<';
        case '"': return '"';
        case '\'': return '\'';
        case '`': return '`';
        default: return 0;
    }
    return 0;
}

int is_symbol(char_t c)
{
  register char_t *p = symbols;

  for (p = symbols; *p != '\0'; p++)
    if (*p == c) return 1;
  return 0;
}

void replace_all(char * str, char oldChar, char newChar)
{
  int i = 0;
  /* Run till end of string */
  while(str[i] != '\0')
  {
    /* If occurrence of character is found */
    if(str[i] == oldChar) {
      str[i] = newChar;
    }
    i++;
  }
}

void cleanup_path(char *path, char *output)
{
  char *dir, final_path[NAME_MAX+1] = "\0";
  const char *list_dirs[20];
  int i = 0;

  final_path[0] = '/';
  dir = strtok(path, "/");

  while( dir != NULL ) {
    if(dir[0] == '.' && dir[1] == '.') {
      i--;
    } else {
      list_dirs[i] = dir;
      i++;
    }
    dir = strtok(NULL, "/");
  }
  for(int z = 0 ; i > z; z++) {
    strcat(final_path, list_dirs[z]);
    if(z != i-1)
      strcat(final_path, "/");
  }
  final_path[NAME_MAX] = '\0';
  strcpy(output, final_path);
  return;
}

point_t find_matching_bracket(buffer_t *bp, int dir)
{
  char_t *p, z, op;
  point_t cp = bp->b_point;
  int depth = 0;
  p = ptr(bp, cp);
  op = *p;
  if((z = is_bracket(*p)) == 0) {
    // TODO: jump over whitespace to get to bracket
    return -1;
  }
  if(dir == -1) {
    cp--;
    while ((*(p = ptr(bp, cp)) != z || depth > 0) && cp >= 0) {
      if(*p == op) {
        depth++;
      } else if(*p == z) {
        depth--;
      }
      cp--;
    }
    if(cp > 0)
      return cp;
  } else {
    cp++;
    while ((*(p = ptr(bp, cp)) != z || depth > 0) && p <= bp->b_ebuf) {
      if(*p == op) {
        depth++;
      } else if(*p == z) {
        depth--;
      }
      cp++;
    }
    if(p < bp->b_ebuf)
      return cp;
  }
  return -1;
}
